package com.yixing.tech.wms.utils;

import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.common.convert.ConvertUtils;
import com.yixing.tech.common.CommonConstant;
import com.yixing.tech.wms.entity.BaseSyncEntity;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Update;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.Optional;
import java.util.UUID;

/**
 * EntityUtils
 *
 * @author yixing tech
 * @since 1.0.0
 */
public abstract class DocumentUtils {

    public static Document newDocument(Object... params) {
        Document document = new Document();
        for (int i = 0; i < params.length; i += 2) {
            document.put(ConvertUtils.convertIfPossible(params[i], String.class), params[i + 1]);
        }
        return document;
    }

    public static Document newBind(String containerCode, String materialCode, String batchNo, int can, String tenantId) {
        Document bind = new Document();
        bind.put("code", UUID.randomUUID().toString().replace("-", ""));
        bind.put("containerCode", containerCode);
        bind.put("optType", newDocument("id", new ObjectId(CommonConstant.OptType.toBind.getCode())));
        bind.put("status", newDocument("id", new ObjectId(CommonConstant.DataStatus.effect.getCode())));
        bind.put("materialCode", materialCode);
        bind.put("batchNo", batchNo);
        bind.put("recommendedNum", can);
        bind.put("createTime", new Date());
        bind.put("tenantId", tenantId);
        bind.put("isDelete", 0);
        return bind;
    }

    public static String wrapDictItem(Document doc, String key) {
        return Optional.ofNullable(doc.get(key, Document.class)).map(x -> x.getString("id")).orElse("");
    }

    public static String unwrapDictItem(Document dictItem) {
       return Optional.ofNullable(dictItem).map(x -> x.getString("id")).orElse("");
    }

    public static Document wrapDictItem(String dictItemCode) {
        return newDocument("id", new ObjectId(dictItemCode));
    }

    public static Update genUpdate(BaseSyncEntity entity) throws BusinessException {
        Update update = new Update();
        for (Field declaredField : entity.getClass().getDeclaredFields()) {
            declaredField.setAccessible(true);
            Object value;
            try {
                value = declaredField.get(entity);
            } catch (IllegalAccessException e) {
                throw new BusinessException("异常字段: ", e);
            }
            update.set(declaredField.getName(), value);
        }
        return update;
    }

}
